package br.com.cfccultura.admin.model.dao.mysql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import br.com.cfccultura.admin.model.dao.IAgendamentoProvaDAO;
import br.com.cfccultura.admin.model.dao.IAlunoDAO;
import br.com.cfccultura.admin.model.dao.ICursoDAO;
import br.com.cfccultura.admin.model.enums.SimNao;
import br.com.cfccultura.admin.model.vo.AgendamentoProva;
import br.com.cfccultura.admin.model.vo.ComputadorProva;
import br.com.cfccultura.admin.model.vo.OrdemServico;

@Repository
public class AgendamentoProvaDAO extends DAO implements IAgendamentoProvaDAO {

	@Autowired
	private ICursoDAO cursoDAO;
	
	@Autowired
	private IAlunoDAO alunoDAO;
	
	@Override
	public List<AgendamentoProva> consultar(AgendamentoProva vo, Boolean provaFuturo) {
		String sql = "SELECT prova.cd_agendamento_prova, prova.cd_aluno, aluno.dc_nome, aluno.dc_cpf, prova.cd_computador_prova, computador.dc_computador_prova, prova.dt_agendamento, prova.id_realizado, prova.id_aprovado, prova.cd_curso, item.cd_ordem_servico " +
				"FROM tb_agendamento_prova prova, tb_computador_prova computador, tb_aluno aluno, tb_ordem_servico_item item " +
				"WHERE computador.cd_computador_prova = prova.cd_computador_prova and aluno.cd_aluno = prova.cd_aluno and item.cd_agendamento_prova = prova.cd_agendamento_prova ";
		Object[] params = {};
		if(vo.getCodigo() != null) {
			sql += "and prova.cd_agendamento_prova = ? ";
			params = new Object[]{vo.getCodigo()};
		} else if(vo.getDataHora() != null) {
			if(!provaFuturo)
				sql += "and prova.dt_agendamento = ? ";
			else
				sql += "and DATE(prova.dt_agendamento) = ? ";
			params = new Object[]{vo.getDataHora()};
		}
		sql += "order by dt_agendamento";
		
		return query(sql, params, new RowMapper<AgendamentoProva>() {
			@Override
			public AgendamentoProva mapRow(ResultSet rs, int arg1) throws SQLException {
				AgendamentoProva vo = new AgendamentoProva();
				vo.setCodigo(rs.getInt("prova.cd_agendamento_prova"));
				vo.setAluno(getAlunoDAO().consultar(rs.getInt("prova.cd_aluno")));
				vo.getAluno().setNome(rs.getString("aluno.dc_nome"));
				vo.getAluno().setCpf(rs.getString("aluno.dc_cpf"));
				vo.setComputador(new ComputadorProva(rs.getInt("prova.cd_computador_prova")));
				vo.getComputador().setDescricao(rs.getString("computador.dc_computador_prova"));
				vo.setDataHora(rs.getTimestamp("prova.dt_agendamento"));
				vo.setRealizado(SimNao.setValue(rs.getInt("prova.id_realizado")));
				vo.setAprovado(SimNao.setValue(rs.getInt("prova.id_aprovado")));
				vo.setCurso(getCursoDAO().consultar(rs.getInt("prova.cd_curso")));
				vo.setOrdemServico(new OrdemServico(rs.getInt("item.cd_ordem_servico")));
				return vo;
			}			
		});
	}
	
	@Override
	public List<AgendamentoProva> consultar(AgendamentoProva vo) {
		return consultar(vo, false);
	}
	
	@Override
	public List<AgendamentoProva> consultaDisponibilidade(Date data) {
		String sql = "SELECT cd_agendamento_prova, dt_agendamento, cd_computador_prova " +
				"FROM tb_agendamento_prova " +
				"WHERE DATE(dt_agendamento) = ? order by dt_agendamento";
		Object[] params = {data};
	
		return query(sql, params, new RowMapper<AgendamentoProva>() {
			@Override
			public AgendamentoProva mapRow(ResultSet rs, int arg1) throws SQLException {
				AgendamentoProva vo = new AgendamentoProva();
				vo.setCodigo(rs.getInt("cd_agendamento_prova"));
				vo.setDataHora(rs.getTimestamp("dt_agendamento"));
				vo.setComputador(new ComputadorProva(rs.getInt("cd_computador_prova")));
				return vo;
			}			
		});
	}
	
	@Override
	public AgendamentoProva consultar(Integer codigo) {
		List<AgendamentoProva> resultado = consultar(new AgendamentoProva(codigo));
		if(resultado.size() > 0) {
			return resultado.get(0);
		}
		return null;
	}
		
	@Override
	public void incluir(final AgendamentoProva vo) {
		KeyHolder keyHolder = new GeneratedKeyHolder();
		update(new PreparedStatementCreator() {			
			@Override
			public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
				String sql = "INSERT INTO tb_agendamento_prova(cd_aluno, cd_computador_prova, dt_agendamento, cd_funcionario_atualizacao, cd_curso) values(?,?,?,?,?)";
				PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

			    ps.setInt(1, vo.getAluno().getCodigo());
				ps.setInt(2, vo.getComputador().getCodigo());
				ps.setTimestamp(3, new java.sql.Timestamp(vo.getDataHora().getTime()));
				ps.setInt(4, vo.getUsuarioSistema().getCodigo());
				ps.setInt(5, vo.getCurso().getCodigo());
			    return ps;
			}
		}, keyHolder);
		
		vo.setCodigo(keyHolder.getKey().intValue());
	}
	
	@Override
	public void alterar(AgendamentoProva vo) {
		String sql = "UPDATE tb_agendamento_prova set dt_agendamento = ?, cd_computador_prova = ?, id_realizado = ?, id_aprovado = ?, cd_funcionario_atualizacao = ?, cd_curso = ? where cd_agendamento_prova = ?";
		update(sql, new Object[] {
			vo.getDataHora(), 
			vo.getComputador().getCodigo(), 
			vo.getRealizado() != null ? vo.getRealizado().getValue() : null, 
			vo.getAprovado() != null ? vo.getAprovado().getValue() : null, 
			vo.getUsuarioSistema().getCodigo(), 
			vo.getCurso().getCodigo(),
			vo.getCodigo()});
	}
	
	@Override
	public void excluir(Integer id) {
		String sql = "DELETE FROM tb_agendamento_prova where cd_agendamento_prova = ?";
		update(sql, new Object[] {id});
	}
	
	public ICursoDAO getCursoDAO() {
		return cursoDAO;
	}
	public void setCursoDAO(ICursoDAO cursoDAO) {
		this.cursoDAO = cursoDAO;
	}
	public IAlunoDAO getAlunoDAO() {
		return alunoDAO;
	}
	public void setAlunoDAO(IAlunoDAO alunoDAO) {
		this.alunoDAO = alunoDAO;
	}

}
